package cn.iocoder.yudao.module.statistics.dal.mysql.shareprofit;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.statistics.dal.dataobject.shareprofit.StoreTradeShareProfitDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.statistics.controller.admin.shareprofit.vo.*;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
 * 门店交易合伙人分润 Mapper
 *
 * @author 万民匠心
 */
@Mapper
public interface StoreTradeShareProfitMapper extends BaseMapperX<StoreTradeShareProfitDO> {

    default PageResult<StoreTradeShareProfitDO> selectPage(StoreTradeShareProfitPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<StoreTradeShareProfitDO>()
                .eqIfPresent(StoreTradeShareProfitDO::getPartnerId, reqVO.getPartnerId())
                .inIfPresent(StoreTradeShareProfitDO::getPartnerId, reqVO.getPartnerIds())
                .betweenIfPresent(StoreTradeShareProfitDO::getReportDate, reqVO.getReportDate())
                .eqIfPresent(StoreTradeShareProfitDO::getPartnerType, reqVO.getPartnerType())
                .eqIfPresent(StoreTradeShareProfitDO::getStoreId, reqVO.getStoreId())
                .likeIfPresent(StoreTradeShareProfitDO::getStoreName, reqVO.getStoreName())
                .inIfPresent(StoreTradeShareProfitDO::getStoreId, reqVO.getStoreIds())
                .orderByDesc(StoreTradeShareProfitDO::getId));
    }

    default List<StoreTradeShareProfitDO> selectHasShareProfitList(StoreTradeShareProfitDO reqDO) {
        return selectList(new MPJLambdaWrapperX<StoreTradeShareProfitDO>()
                .selectAs(StoreTradeShareProfitDO::getPartnerType, StoreTradeShareProfitDO::getPartnerType)  // 合伙人类型
                .selectAs(StoreTradeShareProfitDO::getPartnerId, StoreTradeShareProfitDO::getPartnerId) // 合伙人ID
                .selectAs(StoreTradeShareProfitDO::getStoreId, StoreTradeShareProfitDO::getStoreId) // 门店ID
                .selectSum(StoreTradeShareProfitDO::getShareProfitPayPrice, StoreTradeShareProfitDO::getShareProfitPayPrice)  // 支付金额分润总和
                .selectSum(StoreTradeShareProfitDO::getShareProfitRefundPrice, StoreTradeShareProfitDO::getShareProfitRefundPrice)  // 退款金额分润总和
                .ltIfPresent(StoreTradeShareProfitDO::getReportDate, reqDO.getReportDate())
                .groupBy(StoreTradeShareProfitDO::getPartnerType,StoreTradeShareProfitDO::getPartnerId, StoreTradeShareProfitDO::getStoreId)); // 按合伙人类型、合伙人、店铺分组
    }

    default List<StoreTradeShareProfitDO> selectPartnerShareProfit(StoreTradeShareProfitDO reqDO) {
        return selectList(new MPJLambdaWrapperX<StoreTradeShareProfitDO>()
                .selectAs(StoreTradeShareProfitDO::getPartnerId, StoreTradeShareProfitDO::getPartnerId)
                .selectSum(StoreTradeShareProfitDO::getShareProfitPayPrice, StoreTradeShareProfitDO::getShareProfitPayPrice)  // 支付金额分润总和
                .selectSum(StoreTradeShareProfitDO::getShareProfitRefundPrice, StoreTradeShareProfitDO::getShareProfitRefundPrice)  // 退款金额分润总和
                .eqIfPresent(StoreTradeShareProfitDO::getPartnerId, reqDO.getPartnerId())
                .eqIfPresent(StoreTradeShareProfitDO::getReportDate, reqDO.getReportDate())
                .groupBy(StoreTradeShareProfitDO::getPartnerId)); // 按合伙人分组
    }

    default List<StoreTradeShareProfitDO> selectPartnerShareProfit(List<Long> partnerIds) {
        return selectList(new MPJLambdaWrapperX<StoreTradeShareProfitDO>()
                .selectAs(StoreTradeShareProfitDO::getPartnerId, StoreTradeShareProfitDO::getPartnerId)
                .selectSum(StoreTradeShareProfitDO::getShareProfitPayPrice, StoreTradeShareProfitDO::getShareProfitPayPrice)  // 支付金额分润总和
                .selectSum(StoreTradeShareProfitDO::getShareProfitRefundPrice, StoreTradeShareProfitDO::getShareProfitRefundPrice)  // 退款金额分润总和
                .inIfPresent(StoreTradeShareProfitDO::getPartnerId, partnerIds)
                .groupBy(StoreTradeShareProfitDO::getPartnerId)); // 按合伙人分组
    }


    default PageResult<StoreTradeShareProfitDO> selectPageX(StoreShareProfitPageReqVO reqVO) {
        DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM");
        Function<LocalDate, String> localDateStringFunction = item -> dateFormat.format(item);

        return selectPage(reqVO, new MPJLambdaWrapperX<StoreTradeShareProfitDO>()
                .selectAs(StoreTradeShareProfitDO::getStoreId, StoreTradeShareProfitDO::getStoreId)
                .selectAs(StoreTradeShareProfitDO::getStoreName, StoreTradeShareProfitDO::getStoreName)
                .selectAs("DATE_FORMAT(report_date,'%Y-%m')", StoreTradeShareProfitDO::getReportDate)
                .selectSum(StoreTradeShareProfitDO::getShareProfitPayPrice, StoreTradeShareProfitDO::getShareProfitPayPrice)
                .selectSum(StoreTradeShareProfitDO::getOrderPayPrice, StoreTradeShareProfitDO::getOrderPayPrice)
                .selectSum(StoreTradeShareProfitDO::getShareProfitRefundPrice, StoreTradeShareProfitDO::getShareProfitRefundPrice)
                .selectSum(StoreTradeShareProfitDO::getRefundPrice, StoreTradeShareProfitDO::getRefundPrice)
                .likeIfPresent(StoreTradeShareProfitDO::getStoreName, reqVO.getStoreName())
                .groupBy(StoreTradeShareProfitDO::getStoreId,StoreTradeShareProfitDO::getStoreName,
                        item -> localDateStringFunction.apply(item.getReportDate()))
                .orderByDesc(StoreTradeShareProfitDO::getId));
    }


    @Select("<script> \n" +
            "SELECT sp.store_id,sp.store_name, st.`status`, DATE_FORMAT(report_date,'%Y-%m') as report_date, \n" +
            "sum(sp.order_pay_price - sp.refund_price) as order_pay_price,\n" +
            "sum(sp.share_profit_pay_price-sp.share_profit_refund_price) as share_profit_pay_price\n" +
            "from store_trade_share_profit sp \n" +
            "left join trade_delivery_pick_up_store st on sp.store_id = st.id \n" +
            "<trim prefix=\"WHERE\" prefixOverrides=\"AND | OR\"> \n" +
                "<if test=\"reqVO.storeName != null and reqVO.storeName.length()>0\"> AND sp.store_name like CONCAT('%',#{reqVO.storeName},'%') </if> \n" +
                "<if test=\"reqVO.status != null \"> AND st.`status` = #{reqVO.status} </if> \n" +
                "<if test=\"reqVO.startTime != null \"> AND sp.report_date >= #{reqVO.startTime} </if> \n" +
                "<if test=\"reqVO.endTime != null \"> AND sp.report_date &lt;= #{reqVO.endTime} </if> \n" +
            "</trim> \n" +
            "GROUP BY sp.store_id, sp.store_name,DATE_FORMAT(sp.report_date,'%Y-%m') \n" +
            "order by DATE_FORMAT(sp.report_date,'%Y-%m')" +
            "<if test=\"reqVO.pageSize != -1\">limit #{reqVO.start}, #{reqVO.pageSize} </if> " +
            "</script>")
    List<StoreShareProfitVO> getByStorePage(@Param("reqVO") StoreShareProfitPageReqVO reqVO);



    @Select("<script> \n" +
            "SELECT count(0) from (" +
                "SELECT sp.store_id,sp.store_name, st.`status`, DATE_FORMAT(report_date,'%Y-%m') as report_date, \n" +
                "sum(sp.order_pay_price - sp.refund_price) as order_pay_price,\n" +
                "sum(sp.share_profit_pay_price-sp.share_profit_refund_price) as share_profit_pay_price\n" +
                "from store_trade_share_profit sp \n" +
                "left join trade_delivery_pick_up_store st on sp.store_id = st.id \n" +
                "<trim prefix=\"WHERE\" prefixOverrides=\"AND | OR\"> \n" +
                    "<if test=\"reqVO.storeName != null and reqVO.storeName.length()>0\"> AND sp.store_name like CONCAT('%',#{reqVO.storeName},'%') </if> \n" +
                    "<if test=\"reqVO.status != null \"> AND st.`status` = #{reqVO.status} </if> \n" +
                    "<if test=\"reqVO.startTime != null \"> AND sp.report_date >= #{reqVO.startTime} </if> \n" +
                    "<if test=\"reqVO.endTime != null \"> AND sp.report_date &lt;= #{reqVO.endTime} </if> \n" +
                "</trim> \n" +
                "GROUP BY sp.store_id, sp.store_name,DATE_FORMAT(sp.report_date,'%Y-%m') \n" +
            ") m" +
            "</script>")
    Integer getByStoreCount(@Param("reqVO") StoreShareProfitPageReqVO reqVO);


    @Select("<script> \n" +
            "SELECT sp.partner_id, pt.`name` as partner_name, pt.phone, DATE_FORMAT(sp.report_date,'%Y-%m') as report_date,\n" +
            "sum(sp.share_profit_pay_price - sp.share_profit_refund_price) as share_profit_pay_price \n" +
            "from store_trade_share_profit sp \n" +
            "left join system_partner pt on sp.partner_id = pt.id" +
            "<trim prefix=\"WHERE\" prefixOverrides=\"AND | OR\"> \n" +
                "<if test=\"reqVO.partnerName != null and reqVO.partnerName.length()>0\"> AND pt.`name` like CONCAT('%',#{reqVO.partnerName},'%') </if> \n" +
                "<if test=\"reqVO.startTime != null \"> AND sp.report_date >= #{reqVO.startTime} </if> \n" +
                "<if test=\"reqVO.endTime != null \"> AND sp.report_date &lt;= #{reqVO.endTime} </if> \n" +
            "</trim> \n" +
            "GROUP BY sp.partner_id,DATE_FORMAT(sp.report_date,'%Y-%m') \n" +
            "order by DATE_FORMAT(sp.report_date,'%Y-%m')" +
            "<if test=\"reqVO.pageSize != -1\">limit #{reqVO.start}, #{reqVO.pageSize} </if> \n" +
            "</script>")
    List<PartnerShareProfitVO> getByPartnerPage(@Param("reqVO") StoreShareProfitPageReqVO reqVO);



    @Select("<script> \n" +
            "SELECT count(0) from (" +
            "SELECT sp.partner_id, pt.`name` as partner_name, pt.phone, DATE_FORMAT(sp.report_date,'%Y-%m') as report_date,\n" +
            "sum(sp.share_profit_pay_price - sp.share_profit_refund_price) as share_profit_pay_price \n" +
            "from store_trade_share_profit sp \n" +
            "left join system_partner pt on sp.partner_id = pt.id \n" +
            "<trim prefix=\"WHERE\" prefixOverrides=\"AND | OR\"> \n" +
                "<if test=\"reqVO.partnerName != null and reqVO.partnerName.length()>0\"> AND pt.`name` like CONCAT('%',#{reqVO.partnerName},'%') </if> \n" +
                "<if test=\"reqVO.startTime != null \"> AND sp.report_date >= #{reqVO.startTime} </if> \n" +
                "<if test=\"reqVO.endTime != null \"> AND sp.report_date &lt;= #{reqVO.endTime} </if> \n" +
            "</trim> \n" +
            "GROUP BY sp.partner_id,DATE_FORMAT(sp.report_date,'%Y-%m') \n" +
            ") m" +
            "</script>")
    Integer getByPartnerCount(@Param("reqVO") StoreShareProfitPageReqVO reqVO);

}